package com.molichuxing.services.infrastructure.service.impl;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.dto.TabDto;
import com.molichuxing.framework.utils.ObjectCastUtil;
import com.molichuxing.services.business.dto.response.GoodsSalesStatisticsBizDto;
import com.molichuxing.services.business.dto.response.OrderCarInfoAppDto;
import com.molichuxing.services.contants.OrderStatusConst;
import com.molichuxing.services.infrastructure.bean.OrderExclusivelBean;
import com.molichuxing.services.infrastructure.convertor.Convert;
import com.molichuxing.services.infrastructure.dao.OrderExclusivelMapper;
import com.molichuxing.services.infrastructure.dto.request.create.OrderExclusivelCreateDto;
import com.molichuxing.services.infrastructure.dto.request.modify.OrderDeliveryModifyDto;
import com.molichuxing.services.infrastructure.dto.request.modify.OrderPayModifyDto;
import com.molichuxing.services.infrastructure.dto.response.OrderExclusivelDto;
import com.molichuxing.services.infrastructure.service.OrderExclusivelService;
import com.molichuxing.services.property.*;
import com.molichuxing.services.utils.OrderUtil;
import com.molichuxing.services.utils.TabUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 专属里程订单基础服务
 *
 * @author zoumingyu
 * @date 2019年8月13日
 */
@Service("orderExclusivelService")
public class OrderExclusivelServiceImpl implements OrderExclusivelService {
    private static final Logger logger = LoggerFactory.getLogger(OrderExclusivelServiceImpl.class);

    @Resource
    private OrderExclusivelMapper orderExclusivelMapper;

    /**
     * 专属里程订单信息
     *
     * @param orderCode
     * @return
     */
    @Override
    public OrderExclusivelDto getOrderExclusivel(Long orderCode) {
        return orderCode == null ? null
                : Convert.toOrderExclusivelBeanDto(orderExclusivelMapper.getByOrderCode(orderCode));
    }

    @Override
    public Map<Long, OrderExclusivelDto> getOrderExclusivel(List<Long> orderCodes) {
        Map<Long, OrderExclusivelDto> result = null;
        List<OrderExclusivelBean> beans = orderExclusivelMapper.getByOrderCodeList(orderCodes);
        if (beans == null || beans.isEmpty()) {
            return null;
        }
        result = new HashMap<>();
        for (OrderExclusivelBean bean : beans) {
            result.put(bean.getOrderCode(), Convert.toOrderExclusivelBeanDto(bean));
        }

        return result;
    }

    /**
     * 分页获取专属里程订单信息
     *
     * @param params   listType：列表类型-enum <br/>
     *                 orderStatus：订单状态-enum <br/>
     *                 orderCode：订单号-long <br/>
     *                 userIds：用户id-list <br/>
     *                 storeIds：门店id-list <br/>
     *                 orderTimeStart：下单开始时间-LocalDateTime <br/>
     *                 orderTimeEnd：下单结束时间-LocalDateTime
     * @param pageNum  页数
     * @param pageSize 每页条数
     * @return
     * @throws Exception
     */
    @Override
    public Paged<OrderExclusivelDto> getOrderList(Map<String, Object> params, int pageNum, int pageSize)
            throws Exception {
        // 拼接条件
        OrderExclusivelStatusEnum orderStatusEnum = ObjectCastUtil.castEmun(params.get("orderStatus"),
                OrderExclusivelStatusEnum.class);
        OrderListTypeEnum listTypeEnum = ObjectCastUtil.castEmun(params.get("listType"), OrderListTypeEnum.class);
        if (orderStatusEnum != null) {
            // 订单状态
            if (OrderExclusivelStatusEnum.TRADE_PASS.equals(orderStatusEnum)) {
                // 审核通过状态
                List<Integer> list = new ArrayList<>();
                for (OrderExclusivelStatusEnum orderExclusivelStatus : OrderStatusConst.CREDIT_PASS_EXCLUSIVEL_STATUS) {
                    list.add(orderExclusivelStatus.getValue());
                }
                params.put("orderStatusList", list);
                params.remove("orderStatus");
            } else if (OrderExclusivelStatusEnum.TRADE_REJECTED.equals(orderStatusEnum)) {
                // 审核驳回状态
                OrderExclusivelStatusEnum refundStatusEnum = ObjectCastUtil.castEmun(params.get("refundStatus"),
                        OrderExclusivelStatusEnum.class);
                if (refundStatusEnum == null) {
                    List<Integer> list = new ArrayList<>();
                    for (OrderExclusivelStatusEnum orderExclusivelStatus : OrderStatusConst.CREDIT_REJECT_EXCLUSIVEL_STATUS) {
                        list.add(orderExclusivelStatus.getValue());
                    }
                    params.put("orderStatusList", list);
                    params.remove("orderStatus");
                } else if (OrderExclusivelStatusEnum.TRADE_REJECTED.equals(refundStatusEnum)
                        || OrderExclusivelStatusEnum.TRADE_REFUND.equals(refundStatusEnum)
                        || OrderExclusivelStatusEnum.TRADE_FINISH.equals(refundStatusEnum)) {
                    // 待处理、退款中、已退款
                    params.put("orderStatus", refundStatusEnum.getValue());
                }
            } else if (OrderExclusivelStatusEnum.TRADE_UNAUDIT.equals(orderStatusEnum)) {
                // 待审核状态
                params.put("orderStatusList", Arrays.asList(OrderExclusivelStatusEnum.TRADE_UNAUDIT.getValue(),
                        OrderExclusivelStatusEnum.TRADE_CREDIT_UNAUDIT.getValue()));
                params.remove("orderStatus");
            } else {
                // 其他状态
                params.put("orderStatus", orderStatusEnum.getValue());
            }
        } else {
            // 订单列表类型
            params.put("orderStatusList", OrderUtil.getStatusList(OrderTypeEnum.EXCLUSIVEL, listTypeEnum));
        }

        params.put("listType", listTypeEnum.getValue());
        // 下单开始时间-LocalDateTime
        params.put("orderTimeStart", ObjectCastUtil.castLocalDateTimeStart(params.get("orderTimeStart")));
        // 下单结束时间-LocalDateTime
        params.put("orderTimeEnd", ObjectCastUtil.castLocalDateTimeEnd(params.get("orderTimeEnd")));

        long total = orderExclusivelMapper.getPageCount(params);
        List<OrderExclusivelBean> page = null;
        if (total > 0) {
            page = orderExclusivelMapper.getPage(params, pageNum, pageSize);
        }

        return new Paged<OrderExclusivelDto>(Convert.toOrderExclusivelBeanDto(page), total, pageSize);
    }

    /**
     * 根据用户id查询专属里程订单信息
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public List<OrderExclusivelDto> getOrderListByUser(Integer userId) {
        return userId == null ? null : Convert.toOrderExclusivelBeanDto(orderExclusivelMapper.getByUser(userId, null));
    }

    /**
     * 根据用户id查询有效订单（未取消、未删除）
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public List<OrderExclusivelDto> getNormalByUser(Integer userId) {
        return userId == null ? null
                : Convert.toOrderExclusivelBeanDto(
                orderExclusivelMapper.getByUser(userId, OrderUtil.getNormalStatus(OrderTypeEnum.EXCLUSIVEL)));
    }

    /**
     * 根据车辆id查询专属里程订单信息
     *
     * @param carId 车辆id
     * @return
     */
    @Override
    public List<OrderExclusivelDto> getOrderListByCar(Integer carId) {
        return getOrderListByCar(carId, null);
    }

    /**
     * 根据车辆id查询专属里程订单信息
     *
     * @param carId    车辆id
     * @param storeIds 门店ids
     * @return
     */
    @Override
    public List<OrderExclusivelDto> getOrderListByCar(Integer carId, List<Integer> storeIds) {
        return carId == null ? null : Convert.toOrderExclusivelBeanDto(orderExclusivelMapper.getByCar(carId, storeIds));
    }

    /**
     * 统计每种状态下的数据量
     *
     * @param orderListType 列表类型枚举
     * @return
     */
    @Override
    public List<TabDto> getStatusStatistics(OrderListTypeEnum orderListType) {
        return this.getStatusStatistics(orderListType, null);
    }

    /**
     * 统计每种状态下的数据量
     *
     * @param orderListType 列表类型枚举
     * @return
     */
    @Override
    public List<TabDto> getStatusStatistics(OrderListTypeEnum orderListType, List<Integer> storeIds) {
        List<TabDto> result = new ArrayList<>();
        // 分组查询订单状态数量
        List<TabDto> tabDtoList = orderExclusivelMapper.getStatusStatistics(storeIds);

        List<OrderExclusivelStatusEnum> statusEnumList = null;
        if (OrderListTypeEnum.TRADE_LIST.equals(orderListType)) {
            // 交易列表查询订单状态
            statusEnumList = OrderStatusConst.TRADE_EXCLUSIVEL_STATUS;
            result = TabUtil.exclusivelTransform(statusEnumList, tabDtoList);
        } else if (OrderListTypeEnum.CREDIT_LIST.equals(orderListType)) {
            // 征信审核列表
            statusEnumList = OrderStatusConst.CREDIT_EXCLUSIVEL_STATUS;
            result = TabUtil.exclusivelCreditTransform(statusEnumList, tabDtoList);
        } else if (OrderListTypeEnum.RENEGE_LIST.equals(orderListType)) {
            // 提前退列表
            statusEnumList = OrderStatusConst.RENEGE_EXCLUSIVEL_STATUS;
            result = TabUtil.exclusivelTransform(statusEnumList, tabDtoList);
        }

        return result;
    }

    /**
     * 根据用户id查询订单号
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public List<Long> getOrderCodeByUser(Integer userId) {
        return orderExclusivelMapper.getOrderCodeByUser(userId);
    }

    /**
     * 根据用户id查询订单号
     *
     * @param userIds 用户id
     * @return
     */
    @Override
    public List<Long> getOrderCodeByUser(List<Integer> userIds) {
        return orderExclusivelMapper.getOrderCodeByUsers(userIds);
    }

    /**
     * 根据门店id查询订单号
     *
     * @param storeIds 门店id
     * @return
     */
    @Override
    public List<Long> getOrderCodeByStores(List<Integer> storeIds) {
        return orderExclusivelMapper.getOrderCodeByStores(storeIds);
    }

    @Override
    public List<OrderCarInfoAppDto> getUseCarIdByUser(Integer userId, Integer orderStatus) {
        return orderExclusivelMapper.getCarIdByUser(userId, orderStatus);
    }

    /**
     * 新增专属订单
     *
     * @param createDto
     * @return id
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Integer create(OrderExclusivelCreateDto createDto) {
        OrderExclusivelBean bean = Convert.toOrderExclusivelBean(createDto);
        orderExclusivelMapper.create(bean);
        return bean.getId();
    }

    /**
     * 订单状态修改
     *
     * @param orderCode      订单号
     * @param preOrderStatus 修改前状态
     * @param orderStatus    修改后状态
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public boolean modify(Long orderCode, OrderExclusivelStatusEnum preOrderStatus,
                          OrderExclusivelStatusEnum orderStatus) {
        if (orderExclusivelMapper.modifyStatus(orderCode, preOrderStatus.getValue(), orderStatus.getValue()) > 0) {
            return true;
        }
        return false;
    }

    /**
     * 支付完成修改专属订单
     *
     * @param modifyDto
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean modifyPay(OrderPayModifyDto modifyDto) {
        if (orderExclusivelMapper.modifyPay(Convert.toOrderExclusivelBean(modifyDto),
                OrderExclusivelStatusEnum.TRADE_UNPAID.getValue(),
                OrderExclusivelStatusEnum.TRADE_CANCELED.getValue()) > 0) {
            return true;
        }
        return false;
    }

    /**
     * 统计排序订单商品销量
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> getStatisticsGoods() {
        return orderExclusivelMapper.getStatisticsGoods();
    }

    /**
     * 提车完成修改专属订单
     *
     * @param modifyDto
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean modifyDelivery(OrderDeliveryModifyDto modifyDto) {
        if (orderExclusivelMapper.modifyDelivery(Convert.toOrderExclusivelBean(modifyDto),
                OrderExclusivelStatusEnum.TRADE_UNDELIVERY.getValue()) > 0) {
            return true;
        }
        return false;
    }

    /**
     * 专属订单待审核数量
     *
     * @return
     */
    @Override
    public Integer getOrderExclusivelPendCount() {
        return orderExclusivelMapper.getOrderExclusivelPendCount(OrderExclusivelStatusEnum.TRADE_UNAUDIT.getValue());
    }

    /**
     * 专属超时未还车数量
     *
     * @return
     */
    @Override
    public Integer getExclusivelOvertimeCount() {
        return orderExclusivelMapper.getExclusivelOvertimeCount();
    }


    /**
     * 查询最近N天，每天的专属数量
     *
     * @param days
     * @return
     */
    @Override
    public Map<String, Integer> getExclusivelCountByDay(Integer days) {
        Map<String, Integer> baseMap = new HashMap();
        List<Map<String, Object>> baseList = orderExclusivelMapper.getExclusivelCountByDay(days);
        for (Map<String, Object> map : baseList) {
            String base = null;
            String fare = null;
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                if ("key".equals(entry.getKey())) {
                    base = String.valueOf(entry.getValue());
                } else if ("value".equals(entry.getKey())) {
                    fare = String.valueOf(entry.getValue());
                }
                if (null == base) {
                    continue;
                }
                baseMap.put(base, Integer.valueOf(fare));
            }
        }
        return baseMap;
    }


    /**
     * 查询N天前的专属订单数量
     *
     * @return
     */
    @Override
    public Integer getExclusivelYesterdayCount(Integer days) {

        Integer count = orderExclusivelMapper.getExclusivelYesterdayCount(days);

        return count == null ? 0 : count;
    }

    /**
     * 查询专属订单中所有用车中的
     *
     * @return
     */
    @Override
    public List<OrderExclusivelDto> getExclusivelTradeUse() {
        return Convert.toOrderExclusivelBeanDto(orderExclusivelMapper.getExclusivelTradeUse(OrderExclusivelStatusEnum.TRADE_USE.getValue()));
    }

    /**
     * 查询专属订单信息
     *
     * @param payDate     支付日期
     * @param orderStatus 订单状态
     * @return
     */
    @Override
    public List<OrderExclusivelDto> getExclusivel(LocalDate payDate, OrderExclusivelStatusEnum orderStatus) {
        return Convert
                .toOrderExclusivelBeanDto(
                        orderExclusivelMapper.getExclusivelByPayDate(payDate, orderStatus.getValue()));

    }

    /**
     * 查询当天支付成功的
     *
     * @return
     */
    @Override
    public List<LocalDateTime> getTodayExclusiveCount() {
        return orderExclusivelMapper.getTodayExclusiveCount();
    }

    /**
     * 查询已提车的专属订单
     *
     * @return
     */
    @Override
    public Map<Integer, Integer> getEffectiveOrderVehicleStatistics() {
        Map<Integer, Integer> result = null;
        // 查询不是取消状态且提车的订单
        List<Map<String, Object>> list = orderExclusivelMapper.getEffectiveOrderVehicleStatistics(
                OrderExclusivelStatusEnum.TRADE_CANCELED.getValue());
        if (list == null || list.isEmpty()) {
            return result;
        }
        result = new HashMap<>();
        for (Map<String, Object> map : list) {
            Integer key = Integer.parseInt(map.getOrDefault("vehicleId", 0).toString());
            Integer value = Integer.parseInt(map.getOrDefault("ordersCount", 0).toString());
            result.put(key, value);
        }

        return result;
    }

    /**
     * 查询每个门店下生效订单（提车、续订生效）数量
     *
     * @return
     */
    @Override
    public Map<Integer, Integer> getEffectiveOrderStoreStatistics() {
        Map<Integer, Integer> result = null;
        // 查询不是取消状态且提车的订单
        List<Integer> effectiveStatusList = OrderStatusConst.EXCLUSIVEL_EFFECTIVE_STATUS.stream().map(orderStatus -> {
            return orderStatus.getValue();
        }).collect(Collectors.toList());
        List<Map<String, Object>> list = orderExclusivelMapper.getEffectiveOrderStoreStatistics(effectiveStatusList);
        if (list == null || list.isEmpty()) {
            return result;
        }
        result = new HashMap<>();
        for (Map<String, Object> map : list) {
            Integer key = Integer.parseInt(map.getOrDefault("storeId", 0).toString());
            Integer value = Integer.parseInt(map.getOrDefault("ordersCount", 0).toString());
            result.put(key, value);
        }

        return result;
    }

    /**
     * 查询统计每种商品已支付的专属订单
     *
     * @return
     */
    @Override
    public List<GoodsSalesStatisticsBizDto> getEffectiveOrderGoodsStatistics() {
        List<Map<String, Object>> mapList = orderExclusivelMapper.getEffectiveOrderGoodsStatisticsWherePay(
                OrderSubscribeStatusEnum.TRADE_CANCELED.getValue());
        if (mapList == null || mapList.isEmpty()) {
            return null;
        }
        List<GoodsSalesStatisticsBizDto> result = new ArrayList<>();

        for (Map<String, Object> map : mapList) {
            GoodsSalesStatisticsBizDto dto = new GoodsSalesStatisticsBizDto();
            dto.setGoodsId(Integer.parseInt(map.getOrDefault("goodsId", "0").toString()));
            dto.setVehicleId(Integer.parseInt(map.getOrDefault("vehicleId", "0").toString()));
            dto.setSales(Integer.parseInt(map.getOrDefault("sales", "0").toString()));

            Object t1 = map.get("paymentMethod");
            Object t2 = map.get("isBuyback");
            if (t1 == null || t2 == null) {
                dto.setGoodsName(null);
            } else {
                int paymentMethod = Integer.parseInt(t1.toString());
                boolean isBuyback = Boolean.parseBoolean(t2.toString());
                dto.setGoodsName(map.getOrDefault("transportTime", "0") + "月-" +
                        (OrderPaymentMethodEnum.INSTALLMENT.getValue() == paymentMethod ? "月付-" : "全款-") +
                        (isBuyback ? "回购" : "不回购"));
            }

            result.add(dto);
        }

        result = result.stream().sorted(Comparator.comparing(GoodsSalesStatisticsBizDto::getSales).reversed())
                .collect(Collectors.toList());


        // 查询所有已支付未取消的专属订单信息
//        List<OrderExclusivelBean> beans = orderExclusivelMapper.getHavePaidOrder(
//                OrderExclusivelStatusEnum.TRADE_CANCELED.getValue());
//        if (beans == null || beans.isEmpty()) {
//            return null;
//        }
//        Map<String, GoodsSalesStatisticsBizDto> map = new HashMap<>();
//        beans.forEach(bean -> {
//            GoodsSalesStatisticsBizDto dto = map.get(bean.getGoodsId().toString());
//            if (dto == null) {
//                dto = new GoodsSalesStatisticsBizDto();
//                Convert.toGoodsSalesStatisticsBizDto(bean);
//            } else {
//                dto.setSales(dto.getSales() + 1);
//            }
//        });

        return result;
    }
}
